package mbp.agents;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Level;

import mbp.agents.AMbpServerAgent;
import mbp.base.ServiceType;
import mbp.core.Contract;
import mbp.core.CounterOffer;
import mbp.core.Intention;
import mbp.core.Offer;
import mbp.core.RandObjectBuilder;
import mbp.core.Resource;
import mbp.core.ResourceValidation;
import mbp.core.Service;
import mbp.core.ServiceTypeBuilder;
import mbp.exceptions.ParseExpressionErrorException;
import mbp.message.Copier;
import mbp.tests.RandomObject;

/**
 * Agent Serwer. - PROSTA IMPLEMENTACJA
 * @author Wojciech Wilanski
 *
 */
public class MbpServerAgent extends AMbpServerAgent
{
	
	@Override
	protected void setup()
	{
		super.setup();
		this.logger.setLevel(Level.ERROR);
	}
	
	@Override
	public Service decision(Intention intention) 
	{
		boolean result = true;
		// Pobranie danych intencji
		List<ResourceValidation> rvList = intention.getResourcesOut();
		Integer maxTerm = intention.getRealizeMaxTU();
		
		Service service = Copier.cloneService(patternService);
		
		//pobranie listy zasobow bedacych wynikiem realizacji uslugi wzorcowej
		ArrayList<Resource> rcList = service.getResourcesOut();
		
		// Sprawdzenie cech
		for(int j = 0; j<rcList.size(); j++)
		{
			Resource rc = service.getResourcesOut().get(j);
			//String type = rc.GetType().GetResourceTypeName();
			//ResourceUtility ru = utilitiesList.get(type);
			
			try {
				if(!rvList.get(j).validateFeatures(rc))
				{
					result = false;
				}
			} catch (ParseExpressionErrorException e) {
				// TODO Auto-generated catch block
				logger.error("ParseExpressionErrorException", e);
			}
		}
		
		// Sprawdzenie ilosci zasobow
		for(int j = 0; j<rcList.size(); j++)
		{
			Resource rc = service.getResourcesOut().get(j);
			
			int offerQt = rc.getQuantity();
			int expectedQt = intention.getResourcesOut().get(j).getQuantity();
			if(offerQt!=expectedQt)
			{
				result = false;
			}
		}
		
		//sprawdzenie czasu realizacji kontraktu
		if(result)
		{
			if(service.getServiceRealizeTerm() > maxTerm )
			{
				result = false;
				
			}
		}
		
		logger.info("Decision (Intention) returned: " + result);
		if(result)
		{
			return service;
		}
		else
		{
			return null;
		}
	}

/*	@Override
	public Service decision(Intention intention) 
	{
		Service result = null;
		ResourceValidation rcv = intention.getResourcesOut().get(0);
		Resource rcPattern = patternService.getResourcesOut().get(0);
		
		RandObjectBuilder rob = new RandObjectBuilder();
		List<Resource> rcList = rob.getResourceList(rcv, rcPattern, 5);
		
		if(rcList.size()==0)
		{
			return null;
		}
		
		Resource rc = rcList.get(0);
		result = Copier.cloneService(patternService);
		result.getResourcesOut().set(0, rc);
			
		logger.info("Decision (Intention) returned: " + result);
		return result;
	}*/

	@Override
	public boolean decision(CounterOffer cOffer, Offer lastOffer) 
	{
		boolean result = false;
		
		logger.info("Decision (CounterOffer, Offer) returned: " + result);
		return result;
	}

	@Override
	public boolean decision(CounterOffer cOffer, Contract contract) 
	{
		boolean result = true;
		
		logger.info("Decision (CounterOffer, Contract) returned: " + result);
		return result;
	}

	@Override
	public Offer prepareOffer(Intention intention, Service service) 
	{
		// Utworzenie typu uslugi. Obiekt potrzebny do utworzenia uslugi
		ServiceTypeBuilder stb = new ServiceTypeBuilder("");
		ServiceType type = stb.GetServiceType(patternService.getType().getServiceTypeName());
		Offer offer = new Offer(type, service);
		
		//ResourceValidation rcv = intention.getResourcesOut().get(0);
		//Resource rcPattern = patternService.getResourcesOut().get(0);
		
		//RandObjectBuilder rob = new RandObjectBuilder();
		//Resource rc = rob.getResourceList(rcv, rcPattern, 5).get(0);
		
		
		//offer.getResourcesOut().set(0, rc);
		
		offer.setServerName(new String( getLocalName() ));
		offer.setClientName(new String( intention.getClientName() ));
		offer.setAgentName(new String( intention.getAgentName() ));
		
		logger.info("Prepared offer (Intention)");
		return offer;
	}

	@Override
	public Offer prepareOffer(CounterOffer coffer, Offer lastOffer) 
	{
		Offer offer = lastOffer;
		
		logger.info("Prepared offer (CounterOffer, Offer)");
		return offer;
	}

	@Override
	public Offer prepareOffer(CounterOffer cOffer, Contract contract) 
	{
		Offer offer = new Offer(patternService.getType(), patternService);
		
		logger.info("Prepared offer (CounterOffer, Contract)");
		return offer;
	}

	@Override
	public boolean decisionContract(Offer offer) 
	{
		boolean result = true;
		
		logger.info("DecisionContract (Offer) returned: " + result);
		return result;
	}

}
